package cn.iocoder.yudao.module.wms.service.saleorder;

import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.wms.controller.admin.pomain.vo.PomainSaveReqVO;
import cn.iocoder.yudao.module.wms.dal.dataobject.pomain.PomainsDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.rdrecord10.Rdrecord10DO;
import cn.iocoder.yudao.module.wms.dal.dataobject.saleorder.SaleDetailDO;
import cn.iocoder.yudao.module.wms.dal.mysql.saleorder.SaleDetailMapper;
import cn.iocoder.yudao.module.wms.dal.redis.RedisKeyConstants;
import cn.iocoder.yudao.module.wms.dal.redis.serialNumber.WmsSerialNumberRedisDAO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.wms.controller.admin.saleorder.vo.*;
import cn.iocoder.yudao.module.wms.dal.dataobject.saleorder.SaleOrderDO;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.wms.dal.mysql.saleorder.SaleOrderMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 销售订单主 Service 实现类
 *
 * @author wait
 */
@Service
@Validated
public class SaleOrderServiceImpl implements SaleOrderService {
    public static final String PROCESS_KEY = "saleOrder";
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Resource
    private SaleOrderMapper saleOrderMapper;
    @Resource
    private SaleDetailMapper saleDetailMapper;
    @Resource
    private WmsSerialNumberRedisDAO serialNumberRedisDAO;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createSaleOrder(SaleOrderSaveReqVO createReqVO) {
        // 插入
        String serialNumber = serialNumberRedisDAO.generate(WmsSerialNumberRedisDAO.POMAIN_SERIAL_PREFIX, RedisKeyConstants.SERIAL32);

        SaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, SaleOrderDO.class)
                .setStatus(BpmTaskStatusEnum.SUBMIT.getStatus()).setSerialNumber(serialNumber).setNumber(getSum(createReqVO));
        saleOrderMapper.insert(saleOrder);

        // 插入子表
        createSaleDetailList(saleOrder.getId(), createReqVO.getSaleDetails());


        // 返回
        return saleOrder.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSaleOrder(SaleOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateSaleOrderExists(updateReqVO.getId());
        // 更新
        SaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, SaleOrderDO.class);
        saleOrderMapper.updateById(updateObj);
        if (updateReqVO.getSaleDetails()!=null)
        {
            // 更新子表
            updateSaleDetailList(updateReqVO.getId(), updateReqVO.getSaleDetails());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSaleOrder(Integer id) {
        // 校验存在
        validateSaleOrderExists(id);
        // 删除
        saleOrderMapper.deleteById(id);

        // 删除子表
        deleteSaleDetailByPid(id);
    }

    private void validateSaleOrderExists(Integer id) {
        if (saleOrderMapper.selectById(id) == null) {
            throw exception(SALE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public SaleOrderDO getSaleOrder(Integer id) {
        return saleOrderMapper.selectById(id);
    }

    @Override
    public PageResult<SaleOrderDO> getSaleOrderPage(SaleOrderPageReqVO pageReqVO) {
        return saleOrderMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（销售订单子） ====================

    @Override
    public List<SaleDetailDO> getSaleDetailListByPid(Integer pid) {
        return saleDetailMapper.selectListByPid(pid);
    }

    @Override
    public void updateSaleOrderStatus(SaleOrderSaveReqVO saleOrderSaveReqVO) {
        saleOrderMapper.updateSaleOrderStatus(saleOrderSaveReqVO);
    }

    @Override
    public SaleOrderDO findByProcessInstanceId(String processInstanceId) {
        return saleOrderMapper.findByProcessInstanceId(processInstanceId);
    }

    @Override
    public List<SaleOrderDO> findSaleOrderOperateList() {
        return saleOrderMapper.findSaleOrderOperateList();
    }

    @Override
    public List<SaleDetialRespVO> findSaleDetialByPid(Integer pid) {
        return saleOrderMapper.findSaleDetialByPid(pid);
    }

    @Override
    public SaleDetialRespVO findSaleDetialById(Integer id) {
        return saleOrderMapper.findSaleDetialById(id);
    }

    @Override
    public void updateSaleDetial(SaleDetialRespVO saleDetailDO) {
        saleOrderMapper.updateSaleDetial(saleDetailDO);
    }

    @Override
    public List<SaleDetialRespVO> findSaleDetialOperateList(Integer pid) {
        return saleOrderMapper.findSaleDetialOperateList(pid);
    }

    @Override
    public void businessProcessing(SaleOrderDO saleOrderDO, List<SaleDetailDO> saleDetailDOList) {

    }

    @Override
    public SaleDetialRespVO findSaleDetialByInventoryIdAndPid(Integer inventoryId, Integer pid) {
        return saleOrderMapper.findSaleDetialByInventoryIdAndPid(inventoryId,pid);
    }

    @Override
    public void process(Integer id) {
        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        String processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(),
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                        .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(id)));

        // 将工作流的编号，更新到 业务表单中
        saleOrderMapper.updateById(new SaleOrderDO().setId(id).setProcessInstanceId(processInstanceId).setStatus(BpmTaskStatusEnum.RUNNING.getStatus()));

    }

    private void createSaleDetailList(Integer pid, List<SaleDetailDO> list) {
        list.forEach(o -> o.setPid(pid));
        saleDetailMapper.insertBatch(list);
    }

    private void updateSaleDetailList(Integer pid, List<SaleDetailDO> list) {
        deleteSaleDetailByPid(pid);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createSaleDetailList(pid, list);
    }

    private void deleteSaleDetailByPid(Integer pid) {
        saleDetailMapper.deleteByPid(pid);
    }

    private Double getSum(SaleOrderSaveReqVO saleOrderSaveReqVO)
    {
        //得到总数量
        Double sum=0.0;
        if (saleOrderSaveReqVO.getSaleDetails()!=null){
            for (SaleDetailDO saleDetailDO:saleOrderSaveReqVO.getSaleDetails())
            {
                sum+=saleDetailDO.getQty();
            }
        }
        return sum;
    }

}